#pragma once

#include "BaseListItem.h"
#include "BaseReader.h"
#include "Common.h"
#include "Util.h"

//Name=varName
//Tab=tabName
class CLayoutListItem :
  public CBaseListItem
{
public:
  CLayoutListItem(const TCHAR* name, const TCHAR* tab)
    : CBaseListItem(name), m_name(name), m_tab(tab)
  {}
  virtual ~CLayoutListItem()
  {}

  virtual bool Load(CBaseReader& r);

  // DATA
  virtual CString GetValue() const = 0;
  virtual void SetValue(const CString& val) = 0;

  const CString& GetName() const
  { return m_name; }
  const CString& GetTab() const
  { return m_tab; }
  void SetName(const CString& name)
  { m_name = name; }
  void SetTab(const CString& tab)
  { m_tab = tab; }

protected:
  CString m_name;
  CString m_tab;
};

//
class CLayoutListItemText : public CLayoutListItem
{
public:
  CLayoutListItemText(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItem(name, tab)
  {}

  // Drawing
  virtual void Draw(HDC hdc, const RECT& rc) const;

  // Interface
  virtual bool OnMouseClick(HWND hParent, int x, int y)
  { return DoEditDlg(hParent); }
  virtual bool OnKeyDown(HWND hParent, int vKey);
  virtual bool OnKeyUp(HWND hParent, int vKey)
  { if (vKey == VK_TACTION) return DoEditDlg(hParent); else return false; }

  bool DoEditDlg(HWND hParent, int vKey = 0);

  // DATA
  virtual CString GetValue() const
  { return m_value; }
  virtual void SetValue(const CString& val)
  { m_value = val; }

protected:
  CString m_value;
};

class CLayoutListItemPopup : public CLayoutListItemText
{
public:
  CLayoutListItemPopup(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemText(name, tab)
  {}

  // Interface
  virtual bool OnMouseClick(HWND hParent, int x, int y)
  { return DoSelectorDlg(hParent); }
  virtual bool OnKeyUp(HWND hParent, int vKey)
  { if (vKey == VK_TACTION) return DoSelectorDlg(hParent); else return false; }
  virtual bool OnLongTap(HWND hParent)
  { return DoSelectorDlg(hParent); }

  virtual bool DoSelectorDlg(HWND hParent) = 0;

protected:
  void GetRects(HWND hParent, CRect& rcStart, CRect& rcEnd);
  void GetRects(HWND hParent, int dstHeight, CRect& rcStart, CRect& rcEnd, int& headerHeight);
};

//Min=min value
//Max=max value
class CLayoutListItemInt : public CLayoutListItem
{
public:
  CLayoutListItemInt(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItem(name, tab), m_value(0), m_min(0), m_max(0)
  {}

  virtual bool Load(CBaseReader& r);

  // Drawing
  virtual void Draw(HDC hdc, const RECT& rc) const;

  // Interface
  virtual bool OnMouseClick(HWND hParent, int x, int y)
  { return DoEditDlg(hParent); }
  virtual bool OnKeyDown(HWND hParent, int vKey);
  virtual bool OnKeyUp(HWND hParent, int vKey)
  { if (vKey == VK_TACTION) return DoEditDlg(hParent); else return false; }

  bool DoEditDlg(HWND hParent, int vKey = 0);

  // DATA
  virtual CString GetValue() const
  { TCHAR text[32]; ::_itot(m_value, text, 10); return text; }
  virtual void SetValue(const CString& val)
  { m_value = ::_ttoi(val); m_svalue = val; }

  int GetMin() const
  { return m_min; }
  int GetMax() const
  { return m_max; }
  void SetMin(int min)
  { m_min = min; }
  void SetMax(int max)
  { m_max = max; }

public:
  CString m_svalue;
  int m_value;
  int m_min;
  int m_max;
};

//
class CLayoutListItemCheck : public CLayoutListItem
{
public:
  CLayoutListItemCheck(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItem(name, tab), m_checked(false)
  {}

  virtual bool Load(CBaseReader& r);

  // Drawing
  virtual void Draw(HDC hdc, const RECT& rc) const;

  // Interface
  virtual bool OnMouseClick(HWND hParent, int x, int y)
  { return DoCheck(hParent); }
  virtual bool OnKeyUp(HWND hParent, int vKey)
  { if (vKey == VK_TACTION) return DoCheck(hParent); else return false; }
  virtual bool IsLongTapValid(HWND hParent) { return false; }

  bool DoCheck(HWND hParent);

  // DATA
  virtual CString GetValue() const
  { return m_checked ? TEXT("yes") : TEXT("no"); }
  virtual void SetValue(const CString& val)
  { m_checked = val.CompareNoCase(TEXT("yes")) == 0 || val.CompareNoCase(TEXT("y")) == 0; }

  bool GetChecked() const
  { return m_checked; }
  void SetChecked(bool checked)
  { m_checked = checked; }

public:
  bool m_checked;
};

//Options=Option1;Option2;...;OptionN
class CLayoutListItemStrList : public CLayoutListItemPopup
{
public:
  CLayoutListItemStrList(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemPopup(name, tab)
  {}

  virtual bool Load(CBaseReader& r);

  virtual bool IsLongTapValid(HWND hParent) { return true; }
  virtual bool DoSelectorDlg(HWND hParent);

  // DATA
  virtual CString GetValue() const
  { return m_selection; }
  virtual void SetValue(const CString& val)
  { m_selection = val; m_value = CLanguage::Get(m_selection); }

  const CStringVector& GetOptions() const
  { return m_options; }
  void SetOptions(const CStringVector& options)
  { m_options = options; }

public:
  CStringVector m_options;
  CString       m_selection;
};

//Options=Option1;Option2;...;OptionN
class CLayoutListItemIntList : public CLayoutListItemStrList
{
public:
  CLayoutListItemIntList(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemStrList(name, tab), m_selectionIdx(-1)
  {}

  // DATA
  virtual CString GetValue() const
  { if (m_selectionIdx < 0) return TEXT(""); TCHAR text[32]; ::_itot(m_selectionIdx, text, 10); return text; }
  virtual void SetValue(const CString& val)
  {
    m_selectionIdx = ::_ttoi(val);
    CLayoutListItemStrList::SetValue(m_selectionIdx >= 0 && m_selectionIdx < (int)m_options.size() ? m_options[m_selectionIdx] : TEXT(""));
  }

  int  GetSelectionIdx() const
  { return m_selectionIdx; }
  void SetSelectionIdx(int selectionIdx)
  { m_selectionIdx = selectionIdx; }

protected:
  int m_selectionIdx;
};

//Mask=Lang\*.lng
//HideExt=yes
class CLayoutListItemFileList : public CLayoutListItemStrList
{
public:
  CLayoutListItemFileList(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemStrList(name, tab), m_hideExt(false)
  {}

  virtual bool Load(CBaseReader& r);

  // DATA
  virtual void SetValue(const CString& val)
  { m_selection = val; m_value = m_selection; }

protected:
  void FileToText(const CString& file, CString& text);

protected:
  bool m_hideExt;
};

//Filter=exe;*
//AllowRelative=yes
class CLayoutListItemFile : public CLayoutListItemPopup
{
public:
  CLayoutListItemFile(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemPopup(name, tab), m_allowRelative(true)
  {}

  virtual bool Load(CBaseReader& r);

  // Interface
  virtual bool IsLongTapValid(HWND hParent) { return true; }
  virtual bool DoSelectorDlg(HWND hParent);

  // DATA
  bool GetAllowRelative() const
  { return m_allowRelative; }
  void SetAllowRelative(bool allowRelative)
  { m_allowRelative = allowRelative; }

public:
  CStringVector m_filters;
  bool m_allowRelative;
};

//AllowRelative=yes
class CLayoutListItemFolder : public CLayoutListItemPopup
{
public:
  CLayoutListItemFolder(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemPopup(name, tab), m_allowRelative(true)
  {}

  virtual bool Load(CBaseReader& r);

  // Interface
  virtual bool IsLongTapValid(HWND hParent) { return true; }
  virtual bool DoSelectorDlg(HWND hParent);

  // DATA
  bool GetAllowRelative() const
  { return m_allowRelative; }
  void SetAllowRelative(bool allowRelative)
  { m_allowRelative = allowRelative; }

protected:
  bool m_allowRelative;
};

//
class CLayoutListItemEmailAcc : public CLayoutListItemPopup
{
public:
  CLayoutListItemEmailAcc(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItemPopup(name, tab)
  {}

  virtual bool IsLongTapValid(HWND hParent) { return true; }
  virtual bool DoSelectorDlg(HWND hParent);

  // DATA
  virtual CString GetValue() const
  { return m_account; }
  virtual void SetValue(const CString& val)
  { m_account = val; m_value = CLanguage::Get(m_account); }

public:
  CString       m_account;
};

//
class CLayoutListItemColor : public CLayoutListItem
{
public:
  CLayoutListItemColor(const TCHAR* name, const TCHAR* tab)
    : CLayoutListItem(name, tab), m_color(0)
  {}

  // Drawing
  virtual void Draw(HDC hdc, const RECT& rc) const;

  // Interface
  virtual bool OnMouseClick(HWND hParent, int x, int y)
  { return DoSelectorDlg(hParent); }
  virtual bool OnKeyUp(HWND hParent, int vKey)
  { if (vKey == VK_TACTION) return DoSelectorDlg(hParent); else return false; }
  virtual bool IsLongTapValid(HWND hParent) { return false; }

  bool DoSelectorDlg(HWND hParent);

  // DATA
  virtual CString GetValue() const
  { CString clr; clr.Format(TEXT("%02x%02x%02x"), GetRValue(m_color), GetGValue(m_color), GetBValue(m_color)); return clr; }
  virtual void SetValue(const CString& val)
  { CUtil::ParseColor(val, m_color); if (m_brush.m_hBrush) m_brush.DeleteObject(); m_brush.CreateSolidBrush(m_color); }

  COLORREF GetColor() const
  { return m_color; }
  void SetColor(COLORREF color)
  { m_color = color; }

protected:
  COLORREF m_color;
  CBrush   m_brush;
};